package com.m3958.firstgwt.server.dao;

import java.util.Date;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.m3958.firstgwt.client.types.FlagPermission;
import com.m3958.firstgwt.client.types.ProtectLevel;
import com.m3958.firstgwt.server.accesschecker.ArticleChecker;
import com.m3958.firstgwt.server.accesschecker.SectionChecker;
import com.m3958.firstgwt.server.model.Article;
import com.m3958.firstgwt.server.model.Asset;
import com.m3958.firstgwt.server.model.CacheBreakerItem.ObAction;
import com.m3958.firstgwt.server.model.Section;
import com.m3958.firstgwt.server.model.WebSite;
import com.m3958.firstgwt.server.session.ErrorMessages;
import com.m3958.firstgwt.server.types.ObjectOperation;
import com.m3958.firstgwt.shared.type.CommonField;
import com.m3958.firstgwt.shared.type.SmartParameterName;

public class ArticleChangeStrategy  extends BaseModelChangeStrategy implements ModelChangeStrategy<Article> {

	@Override
	public boolean extraPersistTask(Article model) {
		if(model.getPublishedAt() == null)model.setPublishedAt(new Date());
		model.setPublishedAt(afterAddHourMinutes(model.getPublishedAt()));
		Section s = emp.get().find(Section.class, getReqPs().getRelationModelId());
		if(model.getProtectLevel() == null || model.getProtectLevel().isEmpty()){
			if(s != null){
				model.setProtectLevel(s.getProtectLevel());
			}
		}
		if(model.getProtectLevel() == null || model.getProtectLevel().isEmpty())model.setProtectLevel(ProtectLevel.PUBLIC);
		if(getRso().isSiteEditor(model.getSiteId()) || getRso().isSiteOwner(model.getSiteId())){
			;//如果是站点所有者，可以。
		}else{
			boolean allowAudit = false;
			
			WebSite ws = emp.get().find(WebSite.class, model.getSiteId());
			if(ws != null){//站點一級的允許情況，來到這裡說明不是站點所有者。
				if(ws.getFlagPermission() == FlagPermission.SECTION_AUDITOR){
					allowAudit = true;
				}
			}
			
			if(allowAudit){//在flag允許的情況下，繼續判斷目錄權限。
				if(s!=null){
					SectionChecker ac = injector.getInstance(SectionChecker.class);
					if(ac.hasTreeContainerPerms(Section.class.getName(), s.getId(), ObjectOperation.AUDIT_CONTENT)){
						allowAudit = true;
					}else{
						allowAudit = false;
					}
				}else{
					allowAudit = false;
				}
			}
			if(!allowAudit)model.setAudit(false);
		}
		return true;
	}

	private boolean setInitSection(Article article) {
		if(getReqPs() != null){
			Section s = emp.get().find(Section.class, getReqPs().getRelationModelId());
			if(s != null){
				s.manageRelation(article, true, "", injector.getInstance(ErrorMessages.class));
				article.setDefaultSectionId(s.getId());
				article.getSections().add(s);
				article.setSiteId(s.getSiteId());
				if(article.getProtectLevel() == null || article.getProtectLevel().isEmpty())
					article.setProtectLevel(s.getProtectLevel());
				SectionDao sdao = injector.getInstance(SectionDao.class);//必须用managerelation
				sdao.merge(s);
			}
			return true;
		}else{
			return false;
		}
	}


	@Override
	public boolean extraUpdateTask(Article oldModel,Article newModel) {
		attachAttachments(oldModel);
		oldModel.clearCache(ObAction.UPDATE);
		if(oldModel.isAudit() != newModel.isAudit() && !canAudit(oldModel,newModel)){
			newModel.setAudit(oldModel.isAudit());
		}
		if(newModel.getPublishedAt() == null)newModel.setPublishedAt(new Date());
		return true;
	}
	
	private boolean canAudit(Article oldModel,Article newModel) {
		if(getRso().isSiteEditor(oldModel.getSiteId()) || getRso().isSiteOwner(oldModel.getSiteId())){
			return true;
		}
		boolean allowAudit = false;
		
		WebSite ws = emp.get().find(WebSite.class, newModel.getSiteId());
		if(ws != null){//站點一級的允許情況，來到這裡說明不是站點所有者。
			if(ws.getFlagPermission() == FlagPermission.SECTION_AUDITOR){
				allowAudit = true;
			}
		}

		if(!allowAudit)return false;
		
		ArticleChecker ac = injector.getInstance(ArticleChecker.class);
		for(Section s : oldModel.getSections()){
			//只要有一個不滿足就返回false
			if(!ac.hasTreeContainerPerms(Section.class.getName(), s.getId(), ObjectOperation.AUDIT_CONTENT)){
				return false;
			}
		}
		return allowAudit;
	}

	@Override
	public boolean extraRemoveTask(Article model) {
		model.clearCache(ObAction.DELETE);
		return true;
	}

	@Override
	public boolean afterPersist(Article model) {
		setInitSection(model);
		attachAttachments(model);
		return false;
	}
	
	private void addAt(Article article,JSONObject jo,String usage){
		try {
			Integer oid = jo.getInt(CommonField.ID.getValue());
			Asset a = emp.get().find(Asset.class, oid);
			if("titleImg".equals(usage)){
				article.setTitleImg(a);
			}else if("contentImgs".equals(usage)){
				article.addContentImg(a);
			}else{
				article.addAttachment(a);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void attachAttachments(Article model) {
		model.setTitleImg(null);
		model.getContentImgs().clear();
		model.getAttachments().clear();
		String at = getReqPs().getStringValue(SmartParameterName.ATTACHMENT_JSON);
		if(at == null)return;
		JSONArray ja = null;
		JSONObject jo =JSONObject.fromObject(at);
		if(jo.containsKey("titleImg")){
			addAt(model,jo.getJSONObject("titleImg"),"titleImg");
		}
		
		if(jo.containsKey("contentImgs")){
			ja = jo.getJSONArray("contentImgs");
			for(int j = 0;j<ja.size();j++){
				addAt(model,ja.getJSONObject(j),"contentImgs");
			}
		}
		
		if(jo.containsKey("attachments")){
			ja = jo.getJSONArray("attachments");
			for(int j = 0;j<ja.size();j++){
				addAt(model,ja.getJSONObject(j),"attachments");
			}
		}
	}
	
}
